﻿using BenCaoXuan.Repository.Interface;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace BenCaoXuan.Repository.Instance
{
    public class MySql_Repository<T> : I_Repository<T> where T : class, new()
    {
        private readonly DbContext _context;

        public MySql_Repository(DbContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="t"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void Add(T t)
        {
            _context.Set<T>().Add(t);
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="ie"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void AddRange(IEnumerable<T> ie)
        {
            _context.Set<T>().AddRange(ie);
        }

        /// <summary>
        /// 单个删除
        /// </summary>
        /// <param name="t"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void Delete(T t)
        {
            _context.Set<T>().Remove(t);
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ie"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void DeleteRange(IEnumerable<T> ie)
        {
            _context.Set<T>().RemoveRange(ie);
        }

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IQueryable<T> GetAll(Expression<Func<T, bool>>? where = null)
        {
            var iq=_context.Set<T>();
            return where==null?iq:iq.Where(where);
        }

        /// <summary>
        /// 排序查询
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="isAsc"></param>
        /// <param name="order"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IQueryable<T> GetAll<type>(bool isAsc, Expression<Func<T, type>>? order = null, Expression<Func<T, bool>>? where = null)
        {
            var iq = GetAll(where);
            return isAsc?iq.OrderBy(order!):iq.OrderByDescending(order!);
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="total"></param>
        /// <param name="split"></param>
        /// <param name="take"></param>
        /// <param name="isAsc"></param>
        /// <param name="order"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IQueryable<T> GetAll<type>(out int total, int split=1, int take=10, bool isAsc=true, Expression<Func<T, type>>? order = null, Expression<Func<T, bool>>? where = null)
        {
            var iq = GetAll(isAsc, order, where);
            total=iq.Count();
            return iq.Skip(split).Take(take);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int SaveChanges()
        {
            return _context.SaveChanges();
        }

        /// <summary>
        /// 异步保存
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<int> SaveChangesAsync()
        {
            return _context.SaveChangesAsync();
        }

        /// <summary>
        /// 单个修改
        /// </summary>
        /// <param name="t"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void Update(T t)
        {
            _context.Set<T>().Update(t);
        }

        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="ie"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void UpdateRange(IEnumerable<T> ie)
        {
            _context.Set<T>().UpdateRange(ie);
        }
    }
}
